//
//  MutexLock2Demo.m
//  MultiperThreadTest02
//
//  Created by FelixYin on 2020/4/5.
//  Copyright © 2020 FelixYin. All rights reserved.
//

#import "MutexLock2Demo.h"
#import <pthread.h>

@interface MutexLock2Demo ()

@property (nonatomic,assign) pthread_cond_t cond;
@property (nonatomic,assign) pthread_mutex_t otherLock;
@property (nonatomic,strong) NSMutableArray *dataArray;

@end

@implementation MutexLock2Demo


- (instancetype)init
{
    self = [super init];
    if (self) {
        self.dataArray = [[NSMutableArray alloc] init];
        [self __initLock:&_otherLock];
    }
    return self;
}


- (void)test {
    [[[NSThread alloc] initWithTarget:self selector:@selector(remove) object:nil] start];
    sleep(4);
    [[[NSThread alloc] initWithTarget:self selector:@selector(add) object:nil] start];
}

//添加数据
- (void) add{
    pthread_mutex_lock(&_otherLock);
    NSLog(@"添加元素");
    [self.dataArray addObject:@"数据"];
    //通知一个线程
    pthread_cond_signal(&_cond);
    //通知多个线程 以广播的形式
//    pthread_cond_broadcast(&_cond);
    
    NSLog(@"发送条件信号");
    pthread_mutex_unlock(&_otherLock);
}

//移除最后一个数据
- (void) remove{
    pthread_mutex_lock(&_otherLock);
    if (self.dataArray.count == 0) {
        //当不满足条件时 让处于等待状态，并解锁执行，直到有通知过来，再对_otherLock加锁（通过当前的_cond条件），再执行下面的任务
        NSLog(@"等待条件");
        pthread_cond_wait(&_cond, &_otherLock);
    }
    NSLog(@"删除元素");
    [self.dataArray removeLastObject];
    pthread_mutex_unlock(&_otherLock);
}

//初始化锁
- (void) __initLock:(pthread_mutex_t *) lock{
    /*
     递归锁：允许同一个线程对同一个锁进行重复加锁（不同的线程是没法对同一锁进行加锁）
     
     */
    
    
    //初始化属性
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
//  PTHREAD_MUTEX_DEFAULT (默认锁)  PTHREAD_MUTEX_RECURSIVE（递归锁）
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    
    //初始化锁
    pthread_mutex_init(lock, &attr);
    
    //初始化条件
    pthread_condattr_t conattr;
    pthread_condattr_init(&conattr);
    pthread_cond_init(&_cond, &conattr);
//    pthread_cond_init(&_cond, NULL);//简单形式  可以传NULL
    
    //销毁属性
    pthread_mutexattr_destroy(&attr);
    
}

- (void)dealloc
{
    pthread_mutex_destroy(&_otherLock);
}

@end
